package com.gzx.plugin.tjzy.core.utils.crypter;

import com.google.common.base.Joiner;
import com.google.common.base.Splitter;
import com.google.common.escape.Escaper;
import com.google.common.hash.HashFunction;
import com.google.common.hash.Hashing;
import com.google.common.io.BaseEncoding;
import com.google.common.net.UrlEscapers;

import java.net.URLDecoder;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.Collection;
import java.util.List;
import java.util.Map;


/**
 * 编码工具类
 */
public final class EncodeUtil {
    private EncodeUtil() {
        // Util class
    }

    /**
     * Hash算法 - MD5
     */
    public static final String HASH_ALG_MD5 = "MD5";
    /**
     * Hash算法 - SHA1
     */
    public static final String HASH_ALG_SHA1 = "SHA1";
    /**
     * Hash算法 - SHA256
     */
    public static final String HASH_ALG_SHA256 = "SHA256";
    /**
     * Hash算法 - SHA512
     */
    public static final String HASH_ALG_SHA512 = "SHA512";

    /**
     * 获取hahs函数
     * @param hashAlg hash算法
     * @throws IllegalArgumentException 如果指定的hash算法错误或不被支持
     */
    public static HashFunction getHashFunction(String hashAlg) {
        return switch (hashAlg) {
            case HASH_ALG_MD5 -> Hashing.md5();
            case HASH_ALG_SHA1 -> Hashing.sha1();
            case HASH_ALG_SHA256 -> Hashing.sha256();
            case HASH_ALG_SHA512 -> Hashing.sha512();
            default -> throw new IllegalArgumentException("No such algorithm");
        };
    }

    /**
     * 对数据以指定hash算法进行hash，返回小写的16进制字符串
     * @param hashAlg hash算法
     * @param data 数据
     *
     * @see EncodeUtil#getHashFunction(String)
     */
    public static String hash(String hashAlg, byte[] data) {
        return getHashFunction(hashAlg).hashBytes(data).toString();
    }



    /**
     * BASE64 编/解码器
     */
    public static final BaseEncoding BASE64_ENCODING = BaseEncoding.base64();
    /**
     * BASE64 for URL 编/解码器
     */
    public static final BaseEncoding BASE64_URL_ENCODING = BaseEncoding.base64Url();
    /**
     * BASE64 for URL 编/解码器
     */
    public static final BaseEncoding BASE64_URL_ENCODING_NOPADDING = BaseEncoding.base64Url().omitPadding();
    /**
     * 16进制 编/解码器
     */
    public static final BaseEncoding HEX_ENCODING = BaseEncoding.base16().lowerCase();


    /**
     * 逗号分隔的字符串组合器
     */
    public static final Joiner CS_JOINER = Joiner.on(',');

    /**
     * 逗号分隔的字符串切分器
     */
    public static final Splitter CS_SPLITTER = Splitter.on(',');


    /**
     * 将字符串集拼接为逗号分隔的字符串
     */
    public static String csJoin(Collection<String> strs) {
        if (strs==null){
            return "";
        }
        return CS_JOINER.join(strs);
    }

    /**
     * 将逗号分隔的字符串切分为字符串列表
     */
    public static List<String> csSplit(String str) {
        return CS_SPLITTER.splitToList(str);
    }



    /**
     * 将一组二进制数据编码为16进制字符串
     */
    public static String encodeToHexString(byte[] data) {
        return HEX_ENCODING.encode(data);
    }

    /**
     * 将16进行字符串解码为二进制数据
     */
    public static byte[] decodeHexString(String hexString) {
        return HEX_ENCODING.decode(hexString);
    }

    /**
     * 将一组二进制数据编码为Base64字符串
     */
    public static String encodeToBase64(byte[] data) {
        return BASE64_ENCODING.encode(data);
    }

    /**
     * 将Base64字符串解码为二进制数据
     */
    public static byte[] decodeBase64(String base64String) {
        return BASE64_ENCODING.decode(base64String);
    }

    /**
     * 将一组二进制数据编码为Base64_URL字符串
     */
    public static String encodeToBase64ForUrl(byte[] data) {
        return BASE64_URL_ENCODING_NOPADDING.encode(data);
    }

    /**
     * 将Base64_URL字符串解码为二进制数据
     */
    public static byte[] decodeBase64ForUrl(String base64String) {
        return BASE64_URL_ENCODING.decode(base64String);
    }





    /**
     * URL编码
     */
    public static String urlEncode(String raw) {
        return URLEncoder.encode(raw, StandardCharsets.UTF_8);
    }

    /**
     * URL解码
     */
    public static String urlDecode(String enc) {
        return URLDecoder.decode(enc, StandardCharsets.UTF_8);
    }

    /**
     * 使用 x-www-form-urlencoded 格式编码参数，
     * 调用方应保证参数名与参数值均不是 {@code null}
     * 不会编码参数名，所以应保证参数名是一个已经过URL编码后的值，会编码参数值.toString(),
     * @param params 参数s，参数名 -> 参数值
     */
    public static String encodeUrlParams(Map <String, ?> params) {
        if (params.isEmpty()) {
            return "";
        }
        StringBuilder sb = new StringBuilder();
        Escaper escaper = UrlEscapers.urlFormParameterEscaper();
        for (Map.Entry<String, ?> entry : params.entrySet()) {
            sb.append(entry.getKey())
                    .append("=")
                    .append(escaper.escape(entry.getValue().toString()))
                    .append("&");
        }
        sb.deleteCharAt(sb.length() - 1);
        return sb.toString();
    }



}
